// Tierless
// Copyright © 2010 Alphora
// This file is licensed under a modified BSD-license (see tierless_license.txt).

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Reflection;

using Microsoft.SqlServer.Management.Common;

namespace Tierless.Framework.Server.UnitTests
{
    public class DatabaseSetup
    {
        #region Constants

        const string TESTDATABASE_CONNECTIONSTRING_NAME = "TierlessTest";

        #endregion

        #region Private Members

        static Configuration Config
        {
            get
            {
                return ConfigurationManager.OpenExeConfiguration(Assembly.GetExecutingAssembly().CodeBase.Replace("file:///",null)); 
            }
        }

        static string ExecutionPath
        {
            get
            {
                var path = Path.GetDirectoryName( Assembly.GetExecutingAssembly().Location);
                if (!path.EndsWith(@"\"))
                    path += @"\";
                return path;
            }
        }

        static string TestDatabaseScriptPath
        {
            get
            {
                var scriptPath = Config.AppSettings.Settings["TestDatabaseScriptPath"].Value;
                if (!scriptPath.EndsWith(@"\"))
                    scriptPath += @"\";
                return scriptPath;
            }
        }

        static List<FileInfo> TestDatabaseScripts
        {
            get
            {
				return 
				(
					from p in Config.AppSettings.Settings["TestDatabaseScripts"].Value.Split(',') 
						select new FileInfo(Path.Combine(TestDatabaseScriptPath, p.Trim()))
				).ToList();
            }
        }

        static void ExecuteScript(SqlConnection conn, string strScriptText)
        {
            Console.WriteLine(strScriptText);
            var server = new Microsoft.SqlServer.Management.Smo.Server(new ServerConnection(conn));
            server.ConnectionContext.ExecuteNonQuery(strScriptText);
        }

        #endregion

        #region Unit Tests
        
        private static bool databaseRefreshed;
        
        public static void EnsureDatabaseRefreshed()
        {
			if (!databaseRefreshed)
			{
				Recreate_TestDatabase();
				databaseRefreshed = true;
			}
        }

        public static void Recreate_TestDatabase()
        {
			var cs = Config.ConnectionStrings.ConnectionStrings[TESTDATABASE_CONNECTIONSTRING_NAME].ConnectionString;
			var csb = new SqlConnectionStringBuilder(cs);
			var ic = csb.InitialCatalog;
			csb.InitialCatalog = "master";
            using (var conn = new SqlConnection(csb.ConnectionString))
            {
                foreach (var f in TestDatabaseScripts)
                {
                    using (var sr = f.OpenText())
                    {
                        ExecuteScript(conn, sr.ReadToEnd());
                        // Point the connection to the correct DB after each execute
                        ExecuteScript(conn, String.Format("USE {0}\r\nGO", ic));
                    }
                }
            }
        }

        #endregion
    }
}
